package cn.qu.phizline.common;

/**
 * Created by zh on 17/8/30.
 */
public class ByteBuffer {
    private byte[] bytes = null;

    private int position;   //位置
    private int limit;      //限制
    private int capacity;   //容量

    public ByteBuffer(int capacity) {
        this.capacity = capacity;
        limit = capacity;
        position = 0;
        this.bytes = new byte[capacity];
    }

    public ByteBuffer(byte[] bytes) {
        this(bytes.length);
        System.arraycopy(bytes, 0, this.bytes, 0, capacity);
    }

    public void flip() {
        limit = position;
        position = 0;
    }

    public void clear() {
        position = 0;
        limit = capacity;
    }


    public int position() {
        return position;
    }

    public void position(int position) {
        this.position = position;
    }

    public int limit() {
        return limit;
    }

    public void limit(int limit) {
        this.limit = limit;
    }

    public int capacity() {
        return capacity;
    }

    public void skip(int len) {
        if (position + len <= limit) {
            position += len;
        } else {
            //---
        }
    }

    public void capacity(int capacity) {
        if (this.capacity != capacity) {
            byte[] bytes = new byte[capacity];
            System.arraycopy(this.bytes, 0, bytes, 0, Math.min(capacity, this.capacity));
            this.bytes = bytes;

            this.capacity = this.bytes.length;
            clear();
        }
    }

    public byte read() {
        if (position + 1 <= limit) {
            return bytes[position++];
        } else {
            //
            return -1;
        }
    }

    public byte[] read(int len) {
        if (position + len <= limit) {

            byte[] bytes = new byte[len];
            for (int i = 0; i < len; i++) {
                bytes[i] = read();
            }
            return bytes;
        } else {
            return null;
        }
    }

    public void write(byte[] bytes) {
        if (position + bytes.length <= limit) {
            for (int i = 0; i < bytes.length; i++) {
                this.bytes[position++] = bytes[i];
            }
        }
    }

    public int uint2() {
        return uint(2);
    }

    public void uint2(int n) {
        uint(n, 2);
    }

    public int uint4() {
        return uint(4);
    }

    public void uint4(int n) {
        uint(n, 4);
    }
    public int uint8() {
        return uint(8);
    }

    public void uint8(int n) {
        uint(n, 8);
    }

    public void uint(int n, int len) {
        if (position + len <= limit) {
            int fn = n;
            byte[] tmpBytes = new byte[len];
            for (int i = 0; i < len; i++) {
                tmpBytes[len - 1 - i] = (byte) (fn & 0xF);
                fn >>= 4;
            }

            write(tmpBytes);
        } else {
            //
        }
    }

    public int uint(int len) {
        if (position + len <= limit) {
            int sum = 0;
            for (int i = len; i > 0; i--) {
                int b = ((bytes[position++] & 0xF) << (4 * (i - 1)));
                sum |= b;
            }
            return sum;
        } else {
            //
            return -1;
        }
    }


    public byte[] toBytes() {
        byte[] bytes = new byte[limit - position];
        System.arraycopy(this.bytes, position, bytes, 0, bytes.length);
        return bytes;
    }

    public static void main(String[] args) {
        ByteBuffer buf = new ByteBuffer(new byte[]{12, 12});

        buf.capacity(4);

        buf.skip(2);

        buf.uint2(30000);

        buf.position(0);

        System.out.println(buf.uint2());

        System.out.println(buf.uint2());
    }

}
